/**
 * トグル選択ボタンコンポーネント
 *  usage:
 *   import { SelectButtonGroup, SelectButton } from './SelectButtonGroup';
 *   <SelectButtonGroup name={項目名} value={選択値}>
 *     {CONSTANT.choices.map((choice, idx) => <SelectButton key={idx} value={choice.value} label={choice.label}/>)}
 *   </SelectButtonGroup>
 */
import React, { Component, Children } from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';

import './SelectButtonGroup.css';

export class SelectButton extends Component {
  handleChange(event) {
    const { name } = this.props;
    let value = this.input.value;
    value = value ? Number(value) : null;
    this.props.onChecked(name, value, () => {
      this.props.onChange(name, value);
    });
  }

  render() {
    const { name, value, label, className, checkedValue, disabled } = this.props;
    const id = name + '_' + value;
    const checked = value === checkedValue;
    return (
      <button
        type="button"
        disabled={disabled}
        className={classNames('SelectButton', {
          'checked': checked,
          'disabled': disabled,
        })}
        key={value}
        onClick={this.handleChange.bind(this)}
      >
        <label
          htmlFor={id}
          className={classNames({
            'checked': checked,
            'disabled': disabled,
          }, className)}
          disabled={disabled}
        >
          <span
            className="hiddenRadio"
            style={{ display: 'none' }}
          >
            <input
              type="radio"
              id={id}
              name={name}
              value={value}
              defaultChecked={checked}
              disabled={disabled}
              ref={input => this.input = input}
            />
          </span>
          <span
            className={classNames('labelText', {
              'checked': checked,
              'disabled': disabled,
            })}
          >
            {label}
          </span>
        </label>
      </button>
    );
  }
}

SelectButton.propTypes = {
  value: PropTypes.number,              // 選択値
  label: PropTypes.string.isRequired,   // 選択ラベル
  disabled: PropTypes.bool,             // disabled属性
  onChecked: PropTypes.func.isRequired, // 親コンポーネントのstateを更新するcallback
  onChange: PropTypes.func,             // change event handler
};

SelectButton.defaultProps = {
  disabled: false,
  onChecked: () => {},
  onChange: () => {},
};

export class SelectButtonGroup extends Component {
  constructor(props) {
    super(props);
    this.state = { value: props.value };
  }

  handleChecked(name, value, callback) {
    this.setState({ value }, () => {
      if (this.props.propagate(name, value, true) !== false) {
        callback(name, value);
      }
    });
  }

  render() {
    // eslint-disable-next-line no-unused-vars
    const { name, className, disabled, children, onChange, propagate, ...other } = this.props;
    const newChildren = Children.map(children, child => {
      if (typeof(child) === 'object' && child.type === SelectButton) {
        let newProps = { name, checkedValue: this.state.value, onChecked: this.handleChecked.bind(this) };
        if (disabled) newProps.disabled = disabled;
        if (onChange) newProps.onChange = onChange;
        return React.cloneElement(child, newProps);
      }
      return child;
    });
    return (
      <div className="SelectButtonGroupContainer">
        <div className={classNames('SelectButtonGroup', className, {
          'vertical': Children.count(children) > 2,   // 3個以上は縦並び
        })}
        {...other}>
          {newChildren}
        </div>
      </div>
    );
  }
}

SelectButtonGroup.propTypes = {
  name: PropTypes.oneOfType([PropTypes.string, PropTypes.shape({
    id: PropTypes.string.isRequired,
    label: PropTypes.string.isRequired,
    choices: PropTypes.array.isRequired,
  })]).isRequired,                      // id
  value: PropTypes.number,              // 入力値（初期値）
  className: PropTypes.string,          // class属性
  style: PropTypes.object,              // style属性
  disabled: PropTypes.bool,             // disabled属性（全体）
  onChange: PropTypes.func,             // change event handler
  propagate: PropTypes.func.isRequired, // 親stateを更新するcallback
  children: PropTypes.arrayOf(PropTypes.element).isRequired,
};

SelectButtonGroup.defaultProps = {
  disabled: false,
  onChange: () => {},
  propagate: () => {},
};
